home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / od-amiga / sound.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  5KB  |  183 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Support for Amiga audio.device sound
  5.   * 
  6.   * Copyright 1996, 1997 Samuel Devulder
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "memory.h"
  15. #include "custom.h"
  16. #include "audio.h"
  17. #include "gensound.h"
  18. #include "sounddep/sound.h"
  19. #include "events.h"
  20.  
  21. #include <hardware/custom.h>
  22. #include <hardware/cia.h>
  23.  
  24. #define CIAAPRA 0xBFE001 
  25. #define CUSTOM  0xDFF000
  26.  
  27. static struct Custom *custom= (struct Custom*) CUSTOM;
  28. static struct CIA *cia = (struct CIA *) CIAAPRA;
  29.  
  30. /*
  31.  * Compared to Linux, AF_SOUND, and mac above, the AMIGA sound processing
  32.  * with OS routines is awfull. (sam). But with AHI DOSDriver it is far more
  33.  * easier.
  34.  */
  35.  
  36. char whichchannel[]={1,2,4,8};
  37. struct IOAudio *AudioIO;
  38. struct MsgPort *AudioMP;
  39. struct Message *AudioMSG;
  40.  
  41. unsigned char *buffers[2];
  42. uae_u16 *sndbuffer;
  43. uae_u16 *sndbufpt;
  44. int sndbufsize;
  45. int bufidx, devopen;
  46.  
  47. int have_sound, clockval, oldledstate, period;
  48.  
  49. ULONG AUDIO_FILE;
  50.  
  51. static ULONG TST_AUDIO_FILE(char *buff, char *name, int rate, int bsize)
  52. {
  53.     struct Process *pr = (void*)FindTask(NULL);
  54.     ULONG wd, fd;
  55.  
  56.     if(!name) return 0;
  57.     wd = (ULONG)pr->pr_WindowPtr;
  58.     pr->pr_WindowPtr = (APTR)-1;
  59.     sprintf(buff,name,rate,bsize);
  60.     fd = Open(buff, MODE_NEWFILE);
  61.     pr->pr_WindowPtr = (APTR)wd;
  62.     return fd;
  63. }
  64.  
  65. int setup_sound(void)
  66. {
  67.     sound_available = 1;
  68.     return 1;
  69. }
  70.  
  71. int init_sound (void) 
  72. { /* too complex ? No it is only the allocation of a single channel ! */
  73.   /* it would have been far less painfull if AmigaOS provided a */
  74.   /* SOUND: device handler */
  75.     int rate;
  76.     char buff[256],*devname = NULL;
  77.  
  78.     atexit(close_sound); /* if only amiga os had resource tracking */
  79.     
  80.     /* determine the clock */
  81.     { 
  82.     struct GfxBase *GB;
  83.     GB = (void*)OpenLibrary("graphics.library",0L);
  84.     if(!GB) goto fail;
  85.     if (GB->DisplayFlags & PAL)
  86.         clockval = 3546895;        /* PAL clock */
  87.     else
  88.         clockval = 3579545;        /* NTSC clock */
  89.     CloseLibrary((void*)GB);
  90.     }
  91.  
  92.     /* check buffsize */
  93.     if (currprefs.sound_maxbsiz < 2 || currprefs.sound_maxbsiz > (256*1024)) {
  94.         fprintf(stderr, "Sound buffer size %d out of range.\n", currprefs.sound_maxbsiz);
  95.         currprefs.sound_maxbsiz = 8192;
  96.     } 
  97.     sndbufsize = (currprefs.sound_maxbsiz + 1)&~1;
  98.  
  99.     /* check freq */
  100.     if (!currprefs.sound_freq) currprefs.sound_freq = 1;
  101.     if (clockval/currprefs.sound_freq < 124 || clockval/currprefs.sound_freq > 65535) {
  102.     fprintf(stderr, "Can't use sound with desired frequency %d Hz\n", currprefs.sound_freq);
  103.         currprefs.sound_freq = 22000;
  104.     }
  105.     rate   = currprefs.sound_freq;
  106.     period = (uae_u16)(clockval/rate);
  107.  
  108.     /* check for $AUDIONAME or AUD: or AUDIO: device */
  109.     devname = buff;
  110.     AUDIO_FILE = TST_AUDIO_FILE(buff, getenv("AUDIONAME"),
  111.                                 rate, sndbufsize);
  112.     if(!AUDIO_FILE) /* AHI */
  113.     AUDIO_FILE = TST_AUDIO_FILE(buff, "AUDIO:FREQUENCY=%d/BUFFER=%d",
  114.                                 rate, sndbufsize);
  115.     if(!AUDIO_FILE) /* AUD: */
  116.     AUDIO_FILE = TST_AUDIO_FILE(buff, "AUDIO:FREQUENCY%d/BUFFER%d",
  117.                                 rate, sndbufsize);
  118.     if(!AUDIO_FILE)
  119.     AUDIO_FILE = TST_AUDIO_FILE(buff, "AUD:FREQUENCY%d/BUFFER%d",
  120.                                 rate, sndbufsize);
  121.  
  122.     /* else use audio.device */
  123.     if(!AUDIO_FILE) {
  124.     /* setup the stuff */
  125.     AudioMP = CreatePort(0,0);
  126.     if(!AudioMP) goto fail;
  127.         AudioIO = (struct IOAudio *)CreateExtIO(AudioMP, 
  128.                                                 sizeof(struct IOAudio));
  129.     if(!AudioIO) goto fail;
  130.  
  131.     AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri /*pfew!!*/ = 85;
  132.     AudioIO->ioa_Data = whichchannel;
  133.     AudioIO->ioa_Length = sizeof(whichchannel);
  134.     AudioIO->ioa_AllocKey = 0;
  135.         if(OpenDevice(devname = AUDIONAME, 0, (void*)AudioIO, 0)) goto fail;
  136.     devopen = 1;
  137.         }
  138.  
  139.     /* get the buffers */
  140.     if(AUDIO_FILE) {
  141.         buffers[0] = (void*)AllocMem(sndbufsize,MEMF_ANY|MEMF_CLEAR);
  142.         buffers[1] = NULL;
  143.         if(!buffers[0]) goto fail;
  144.     } else {
  145.         buffers[0] = (void*)AllocMem(sndbufsize,MEMF_CHIP|MEMF_CLEAR);
  146.         buffers[1] = (void*)AllocMem(sndbufsize,MEMF_CHIP|MEMF_CLEAR);
  147.         if(!buffers[0] || !buffers[1]) goto fail;
  148.     }
  149.     bufidx = 0;
  150.     sndbuffer = sndbufpt = (uae_u16*)buffers[bufidx];
  151.  
  152.     oldledstate = cia->ciapra & (1<<CIAB_LED);
  153.     cia->ciapra |= (1<<CIAB_LED);
  154.  
  155.     sample_evtime = (long)maxhpos * maxvpos * 50 / rate;
  156.     init_sound_table8 ();
  157.     eventtab[ev_sample].handler = sample8_handler;
  158.  
  159.     fprintf(stderr, "Sound driver found and configured for %d bits "
  160.                     "at %d Hz, buffer is %d bytes (%s)\n",
  161.                     8, rate, sndbufsize,devname);
  162.  
  163.     sound_available = 1;
  164.     return 1;
  165. fail:
  166.     sound_available = 0;
  167.     return 0;
  168. }
  169.  
  170. void close_sound(void)
  171. {
  172.     if(AUDIO_FILE) Close(AUDIO_FILE);
  173.     if(devopen) {CloseDevice((void*)AudioIO);devopen = 0;}
  174.     if(AudioIO) {DeleteExtIO((void*)AudioIO);AudioIO = NULL;}
  175.     if(AudioMP) {DeletePort((void*)AudioMP);AudioMP = NULL;}
  176.     if(buffers[0]) {FreeMem((APTR)buffers[0],sndbufsize);buffers[0] = 0;}
  177.     if(buffers[1]) {FreeMem((APTR)buffers[1],sndbufsize);buffers[1] = 0;}
  178.     if(sound_available) {
  179.         cia->ciapra = (cia->ciapra & ~(1<<CIAB_LED)) | oldledstate;
  180.     sound_available = 0;
  181.     }
  182. }
  183.